package ru.cannabis;

import ru.cannabis.job.AbstractJob;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.List;

public class PickupServer extends AbstractJob
{
	private int nioMessageMaxLength = 8162;
	private List<Integer> ports;
	private NioSocketAcceptor acceptor;

	@Autowired
	private IoHandlerAdapter handler;

	protected PickupServer(List<Integer> ports) {
		this.ports = ports;
	}

	public void setNioMessageMaxLength() {
		this.nioMessageMaxLength = nioMessageMaxLength;
	}

	@Override
	protected void execute()
    {
        acceptor = new NioSocketAcceptor(1);

		if (handler == null) return;

		acceptor.setHandler(handler);
		acceptor.setCloseOnDeactivation(true);

		TextLineCodecFactory factory = new TextLineCodecFactory(Charset.forName("UTF-8"));
		factory.setDecoderMaxLineLength(nioMessageMaxLength);
		factory.setEncoderMaxLineLength(nioMessageMaxLength);

		acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(factory));
		acceptor.getFilterChain().addLast("logger", new LoggingFilter());

		for (Integer port : ports)
        {
			try
            {
				acceptor.bind(new InetSocketAddress(port));

				log.debug(String.format("Mafia server started on port %d", port));
                System.out.println(String.format("Mafia server started on port %d", port));
			}
            catch (BindException e)
            {
				log.error(String.format("Unable to bind on port %d", port));
                System.out.println(String.format("Unable to bind on port %d", port));
			}
            catch (IOException e)
            {
				log.error(String.format("%s while trying to bind on port %d", e.getMessage(), port));
                System.out.println(String.format("Unable to bind on port %d", port));
			}
		}
	}
}
